/*
 * fabryka.h
 *
 * Copyright (C) 2008, 2009
 *
 * Lukasz Bieniasz-Krzywiec
 * Dariusz Leniowski
 */

#ifndef FABRYKA_H_
#define FABRYKA_H_

#include "../config.h"

#include "osobnik.h"
#include "osobnik_mieszany.h"

extern int      RODZAJOW;
extern osobnik  **populacja;
extern int      rodz[MAX_RODZAJOW+1];

/*
 * Modul generujacy nowych osobnikow
 */

class fabryka {
public:
  fabryka() {}
  virtual ~fabryka() {}

  /*
   * Utworz nowego osobnika
   * Argumenty:
   * - rodzaj -- rodzaj osobnika, ktory ma zostac utworzony (ALLC, etc.)
   * - n -- miejsce w tablicy populacji, gdzie ma sie pojawic nowy osobnik
   * Zalozenia:
   * - Populacja miesci sie w globalnej tablicy populacja
   * - n jest poprawnym indeksem tej tablicy
   * Wynik:
   * - jezeli na miejscu n znajdowal sie juz osobnik, to zostanie od usuniety
   * - na miejscu n pojawi sie nowy osobnik o rodzaju rodzaj
   */
  static void nowy(int rodzaj, int n)
  {
    ASSERT(0 <= n && n < N);
    ASSERT(0 < rodzaj && rodzaj <= MAX_RODZAJOW);

    if(populacja[n]) // Jezeli na miejscu n byl juz osobnik to
    {
      rodz[populacja[n]->rodzaj]--; // zaaktualizuj licznik
      delete populacja[n]; // i go usun
    }

    rodz[rodzaj]++;

    if (rodzaj > 100000) {
      switch (rodzaj % 1000) {
        case LUBI_LOSOWY:
          populacja[n] = (osobnik*) new osobnik_mieszany<lubi_losowy>(n, rodzaj, (real) -(rodzaj / 100000 - 2));
          break;
        case LUBI_WSZYSTKICH:
          populacja[n] = (osobnik*) new osobnik_mieszany<lubi_wszystkich>(n, rodzaj, (real) -(rodzaj / 100000 - 2));
          break;
        case LUBI_WSPOLPRACE:
          populacja[n] = (osobnik*) new osobnik_mieszany<lubi_wspolprace>(n, rodzaj, (real) -(rodzaj / 100000 - 2));
          break;
        case LUBI_WSPOLPRACE2:
          populacja[n] = (osobnik*) new osobnik_mieszany<lubi_wspolprace2>(n, rodzaj, (real) -(rodzaj / 100000 - 2));
          break;
        case LUBI_FITNESS:
          populacja[n] = (osobnik*) new osobnik_mieszany<lubi_fitness>(n, rodzaj, (real) -(rodzaj / 100000 - 2));
          break;
        default:
          blad("fabryka.nowy(): Zly rodzaj osobnika");
          break;
      }
    } else {
      switch(rodzaj) {
        case OSOBNIK_ALLC:
          populacja[n] = (osobnik*) new osobnik_allc(n); // nowy
          break;
        case OSOBNIK_ALLD:
          populacja[n] = (osobnik*) new osobnik_alld(n);
          break;
        case OSOBNIK_NIETOPERZ_ZLY:
          populacja[n] = (osobnik*) new osobnik_nietoperz_zly(n);
          break;
        case OSOBNIK_NIETOPERZ_DOBRY:
          populacja[n] = (osobnik*) new osobnik_nietoperz_dobry(n);
          break;
        default:
          blad("fabryka.nowy(): Zly rodzaj osobnika");
          break;
      }
    }
  }
};

#endif /* FABRYKA_H_ */
